/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.store.client.components;

import java.util.ArrayList;
import java.util.List;

import com.elf.gwt.common.client.components.CommonSimpleComponent;
import com.elf.gwt.common.client.model.AbstractModel;
import com.elf.gwt.common.client.model.AttributeValueModel;
import com.elf.gwt.common.client.model.CartModel;
import com.elf.gwt.common.client.model.DetailedProductModel;
import com.elf.gwt.common.client.model.ProductModel;
import com.elf.gwt.common.client.utils.CommonUtils;
import com.elf.gwt.store.client.GWTCommerceConstants;
import com.elf.gwt.store.client.StoreComponentController;
import com.elf.gwt.store.client.utils.StoreUtils;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;

/**
 * 
 */

public class CartComponent extends StoreSimpleComponent
{
	protected static CartSummaryComponent cartSummaryComponent = null;
	
	protected List<CheckBox> checkBoxes;
	protected List<TextBox> qtyTextBoxes;
	protected Grid cartTable;
	protected Grid bodyPanel;
	protected CartModel cartModel;
	
	/**
	 * Constructor
	 */
	public CartComponent(StoreComponentController controller, String stylePrefix)
	{
		super(controller, stylePrefix, null, false);
		
		cartModel = new CartModel();
		checkBoxes = new ArrayList<CheckBox>();
		qtyTextBoxes = new ArrayList<TextBox>();

		bodyPanel = new Grid(4,1);
		bodyPanel.setWidth("100%");
		bodyPanel.addStyleName("ComponentBodyPanel");
		bodyPanel.addStyleName(getHandle() + "BodyPanel");
		panel.setWidget(1, 0, bodyPanel);
		bodyPanel.getCellFormatter().setHorizontalAlignment(1, 0, HasHorizontalAlignment.ALIGN_RIGHT);
	}

	public boolean updateFromHistoryParameters(String[] params)
	{
		storeController.getMultipleResultsComponent().addComponent(this);

		//Don't look for new products
		CommonSimpleComponent alwaysAskComponent = controller.getComponent("NewProductsComponent", false);
		if (alwaysAskComponent != null) storeController.getMultipleResultsComponent().removeComponent(alwaysAskComponent);

		return super.updateFromHistoryParameters(params);
	}

	public void build()
	{		
			checkBoxes.clear();
			qtyTextBoxes.clear();

			List<DetailedProductModel> productModels = cartModel.getProducts();
			int sz = productModels.size();

			/* Cart Table */
			cartTable = new Grid(sz+1, 4);
			cartTable.addStyleName(getHandle() + "CartTable");
			CellFormatter cf = cartTable.getCellFormatter();
			cf.addStyleName(0, 0, getHandle() + "CartTableHeading");
			cf.addStyleName(0, 1, getHandle() + "CartTableHeading");
			cf.addStyleName(0, 2, getHandle() + "CartTableHeading");
			cf.addStyleName(0, 3, getHandle() + "CartTableHeading");
			cf.setWidth(0, 1, "100%");

			GWTCommerceConstants constants = storeController.getStoreConstants();
			
			cartTable.setText(0, 0, constants.CartComponentSubTableRemove());
			cartTable.setText(0, 1, constants.CartComponentSubTableProducts());
			cartTable.setText(0, 2, constants.CartComponentSubTableQuantity());
			cartTable.setText(0, 3, constants.CartComponentSubTableTotal());

			for (int i= 0; i < sz; i++)
			{
				DetailedProductModel productModel = productModels.get(i);
				cf.setWidth(i+1, 1, "100%");
				cf.addStyleName(i+1, 0, getHandle() + "CartTableCell");
				cf.addStyleName(i+1, 1, getHandle() + "CartTableCell");
				cf.addStyleName(i+1, 2, getHandle() + "CartTableCell");
				cf.addStyleName(i+1, 3, getHandle() + "CartTableCell");
				cf.addStyleName(i+1, 3, "Price");
				cf.setHorizontalAlignment(i+1, 0, HasHorizontalAlignment.ALIGN_CENTER);
				cf.setHorizontalAlignment(i+1, 1, HasHorizontalAlignment.ALIGN_LEFT);
				cf.setHorizontalAlignment(i+1, 2, HasHorizontalAlignment.ALIGN_CENTER);
				cf.setHorizontalAlignment(i+1, 3, HasHorizontalAlignment.ALIGN_RIGHT);

				//Checkbox for removing item from cart
				CheckBox checkBox = new CheckBox();
				checkBoxes.add(checkBox);
				cartTable.setWidget(i+1, 0, checkBox);

				//Product
				List<AttributeValueModel> values = productModel.getCartOptions();
				int osz = values.size();
				Grid productGrid = new Grid(1+osz,1);
				productGrid.getCellFormatter().addStyleName(0, 0, "ComponentLink");
				productGrid.getCellFormatter().addStyleName(0, 0, getHandle() + "CartTableProductHeading");
				productGrid.setText(0, 0, productModel.getName());
				for (int j= 0; j < osz; j++)
				{
					productGrid.getCellFormatter().addStyleName(j+1, 0, getHandle() + "CartTableProductOption");
					AttributeValueModel valueModel = values.get(j);
					String txt = "- " + valueModel.getAttributeName() + ": " + valueModel.getName();
					productGrid.setText(j+1, 0, txt);
				}

				productGrid.addClickHandler(tableHandler);
				
				Image image = new Image();
				image.addStyleName("ComponentLink");
				image.setUrl(StoreUtils.getImageProductsDirectory() + productModel.getImage());
				String[] imageSize = productModel.getImageSize();
				imageSize = AbstractModel.adjustedImageSize(
						Double.valueOf(imageSize[0]).doubleValue(), 
						Double.valueOf(imageSize[1]).doubleValue(), 
						StoreComponentController.categoriesComponent.categoryMetaModel.getSmallImageWidthMax(), 
						StoreComponentController.categoriesComponent.categoryMetaModel.getSmallImageHeightMax());
				image.setSize(imageSize[0], imageSize[1]);
				image.addClickHandler(tableHandler);
				HorizontalPanel productPanel = new HorizontalPanel();
				productPanel.add(image);
				productPanel.add(productGrid);

				cartTable.setWidget(i+1, 1, productPanel);

				//Quantity
				TextBox qtyTextBox = new TextBox();
				int quantity = productModel.getCartQuantity();
				qtyTextBox.setText(String.valueOf(quantity));
				qtyTextBox.setWidth("50px");
				cartTable.setWidget(i+1, 2, qtyTextBox);
				qtyTextBoxes.add(qtyTextBox);

				//Price
				double totalPrice = productModel.getCartPrice() * quantity;
				cartTable.setHTML(i+1, 3, CommonUtils.priceDisplay(StoreComponentController.currenciesComponent.getCurrencyModel(), totalPrice));
			}
			bodyPanel.setWidget(0, 0, cartTable);

			//Total Price
			double cartTotalPrice = cartModel.getCartPrice();

			bodyPanel.setHTML(1, 0, CommonUtils.priceDisplay(StoreComponentController.currenciesComponent.getCurrencyModel(), cartTotalPrice));
			bodyPanel.setWidget(2, 0, new InlineHTML("&nbsp;"));

			HorizontalPanel buttonPanel = new HorizontalPanel();
			buttonPanel.setWidth("100%");

			Button updateButton = new Button(constants.CartComponentUpdate(), updateClickHandler);
			updateButton.addStyleName(getHandle() + "UpdateButton");

			Button continueButton = new Button(constants.CartComponentContinueShopping(), continueClickHandler);
			continueButton.addStyleName(getHandle() + "ContinueButton");

			Button checkoutButton = new Button(constants.CartComponentCheckout(), checkoutClickHandler);
			checkoutButton.addStyleName(getHandle() + "CheckoutButton");

			buttonPanel.add(updateButton);
			buttonPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
			buttonPanel.add(continueButton);
			buttonPanel.add(checkoutButton);
			bodyPanel.setWidget(3, 0, buttonPanel);
			
		onBuilt();
	}

	protected ClickHandler updateClickHandler = new ClickHandler() {
		public void onClick(ClickEvent event) {
			StoreComponentController.enableWait();
			
			int sz = qtyTextBoxes.size();
			for (int i = 0; i < sz; i++)
			{
				TextBox qtyTextBox = qtyTextBoxes.get(i);
				int qty = Integer.parseInt(qtyTextBox.getValue());
				DetailedProductModel pmodel = cartModel.getProducts().get(i);
				pmodel.setCartQuantity(qty);
			}
			
			sz = checkBoxes.size();
			for (int i = sz-1; i> -1; i--)
			{
				CheckBox checkBox = checkBoxes.get(i);
				if (checkBox.getValue())
				{
					cartModel.getProducts().remove(i);
				}
			}
			cartModel.setUploadCartRequired(true);
			cartModel.updateProductPrices();

			StoreComponentController.disableWait();
			Window.scrollTo(0, 0);
			if (cartSummaryComponent == null) cartSummaryComponent = (CartSummaryComponent)controller.getComponent("CartSummaryComponent");
			cartSummaryComponent.build();
			build();
		}
	};

	protected ClickHandler continueClickHandler = new ClickHandler() {
		public void onClick(ClickEvent event) {
			if (StoreComponentController.productComponent.getProductModel().getId() < 1)
			{
				onSelection("CategoriesComponent--" + StoreComponentController.categoriesComponent.getCategoryModel().getId() 
						+ "--" + StoreComponentController.manufacturersComponent.getManufacturerModel().getId());
			}
			else
			{
				ProductModel productModel = StoreComponentController.productComponent.getProductModel();
				onSelection("ProductComponent--" + productModel.getId() 
						+ "--" + productModel.getCategoryId()
						+ "--" + StoreComponentController.manufacturersComponent.getManufacturerModel().getId());
			}
		}
	};

	protected ClickHandler checkoutClickHandler = new ClickHandler() {
		public void onClick(ClickEvent event) {
			Window.scrollTo(0, 0);
			onSelection("CheckoutComponent");
		}
	};

	protected ClickHandler tableHandler= new ClickHandler() {
		public void onClick(ClickEvent event)
		{
			HTMLTable.Cell cell = cartTable.getCellForEvent(event);
			int index = cell.getRowIndex()-1;
			List<DetailedProductModel> productModels = cartModel.getProducts();
			ProductModel productModel = productModels.get(index);
			onSelection("ProductComponent--" + productModel.getId() + "--" + productModel.getCategoryId() + "--0");
		}
	};

	public CartModel getCartModel() {
		return cartModel;
	}

}
